package avicit.bdp.dms.dss.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.service.service.CommonTypeService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.CheckParaUtils;
import avicit.bdp.common.utils.EntityUtils;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.dms.dss.dao.DssSubscribeDAO;
import avicit.bdp.dms.dss.dto.DataResourceDTO;
import avicit.bdp.dms.dss.dto.DssSubscribeDTO;
import avicit.bdp.dms.dss.dto.DssUserDTO;
import avicit.bdp.dms.dss.enums.AuditStatus;
import avicit.bdp.dms.dss.enums.ReleaseType;
import avicit.bdp.dms.dss.enums.ResourceStatus;
import avicit.bdp.dms.dss.enums.ResourceType;
import avicit.bdp.dms.dss.vo.DssSubScribeVo;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.SysUserClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 数据资源申请表服务
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DssSubscribeService extends BaseService<DssSubscribeDAO, DssSubscribeDTO> {

    @Autowired
    private DssSubscribeDAO subscribeDao;
    @Autowired
    private DataResourceService dataResourceService;
    @Autowired
    private CommonTypeService commonTypeService;
    @Autowired
    private SysUserClient sysUserClient;
    @Autowired
    private DssUserService userService;
    @Autowired
    private ConvertColumnClient convertColumnClient;

    /**
     * 分页查询订阅列表
     *
     * @param typeId      分类ID
     * @param auditStatus 审核状态
     * @param keyWord     关键词
     * @return 分页列表
     */
    public QueryRespBean<DssSubScribeVo> getSubscribeList(String typeId, Integer auditStatus, String keyWord,
                                                          String userId, Integer currentPage, Integer pageSize) throws Exception {
        List<String> typeIdList = new ArrayList<>();
        if (StringUtils.isNotEmpty(typeId)) {
            commonTypeService.typeIdConvert(typeId, typeIdList, "dataServiceType");
        }

        QueryRespBean<DssSubScribeVo> queryRespBean = new QueryRespBean<>();
        // 文档密级
        List<String> wordSecretList = ThreadContextHelper.getWordSecretList();
        com.github.pagehelper.PageHelper.startPage(currentPage, pageSize);

        Page<DssSubScribeVo> subscribeList = subscribeDao.selectSubscribeList(typeIdList, auditStatus, keyWord, userId, wordSecretList);
        valueConvert(subscribeList);
        queryRespBean.setResult(subscribeList);
        BdpLogUtil.log4Query("服务订阅审核模块", "服务订阅", queryRespBean);
        return queryRespBean;
    }

    private void valueConvert(Page<DssSubScribeVo> subscribeList) {
        //循环组装请求数据
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (DssSubScribeVo dssSubScribeVo : subscribeList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dssSubScribeVo.getUserId());
            BusinessUtil.createConvertSet(convertFormData, Constants.BDP_DATA_SECRET_LEVEL_KEY, dssSubScribeVo.getSecretLevel());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (DssSubScribeVo dssSubScribeVo : subscribeList) {
                dssSubScribeVo.setReleaseTypeString(ReleaseType.getDescByCode(dssSubScribeVo.getReleaseType()));
                dssSubScribeVo.setTypeString(ResourceType.getDescByCode(dssSubScribeVo.getType()));
                dssSubScribeVo.setStatusString(ResourceStatus.getDescByCode(dssSubScribeVo.getStatus()));
                dssSubScribeVo.setAuditStatusString(AuditStatus.getDescByCode(dssSubScribeVo.getAuditStatus()));
                dssSubScribeVo.setSubscribeUser(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER,
                        dssSubScribeVo.getUserId()));
                dssSubScribeVo.setUserId(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER,
                        dssSubScribeVo.getUserId()));
                dssSubScribeVo.setSecretLevelName(BusinessUtil.convertFormat(
                        convertResultData, Constants.BDP_DATA_SECRET_LEVEL_KEY, dssSubScribeVo.getSecretLevel()));
            }
        }
    }

    /**
     * 审核
     *
     * @param subscribeDTO 订阅DTO
     */
    public void audit(DssSubscribeDTO subscribeDTO) {
        CheckParaUtils.checkObjectValidity(subscribeDTO.getAuditStatus(), logger, "审核状态必填");

        DssSubscribeDTO dssSubscribeDTO = this.selectByPrimaryKey(subscribeDTO.getId());
        CheckParaUtils.checkDbObjectValidity(dssSubscribeDTO, logger, String.format("没有查到数据，请确保id:%s的订阅数据是否存在", subscribeDTO.getId()));

        dssSubscribeDTO.setAuditStatus(subscribeDTO.getAuditStatus());
        dssSubscribeDTO.setAuditBy(ThreadContextHelper.getUserId());
        dssSubscribeDTO.setAuditDate(new Date());
        dssSubscribeDTO.setAuditOpinion(subscribeDTO.getAuditOpinion());
        this.updateByPrimaryKeySelective(dssSubscribeDTO);

        String logTitle = "审核服务订阅：【" + JSONObject.toJSONString(dssSubscribeDTO) + "】";
        BdpLogUtil.log("服务审核模块", logTitle, PlatformConstant.OpType.update);

        // 用户订阅审核通过后，自动生成用户信息
        if(AuditStatus.PASSED.getCode() == subscribeDTO.getAuditStatus()){
            DssUserDTO dssUserQuery = new DssUserDTO();
            dssUserQuery.setUserId(dssSubscribeDTO.getUserId());
            if(userService.selectCount(dssUserQuery) == 0){

                // 根据用户ID调用平台服务返回用户名称
                Map<String, Set<String>> convertFormData = new HashMap<>();
                try{
                    BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dssSubscribeDTO.getUserId());
                }catch (Exception e){
                    logger.error("根据用户ID调用平台服务返回用户名称异常,", e.getMessage());
                }

                DssUserDTO dssUser = new DssUserDTO();
                dssUser.setId(ComUtil.getId());
                dssUser.setUserId(dssSubscribeDTO.getUserId());
                if (convertFormData.size() > 0) {
                    Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
                    dssUser.setUserName(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER,
                            dssSubscribeDTO.getUserId()));
                }
                dssUser.setDayCount(1000);
                dssUser.setValidDate(null);
                dssUser.setToken(ComUtil.getId());
                EntityUtils.setCreateAndUpdateInfo(dssUser);
                userService.insert(dssUser);

                //记录日志
                BdpLogUtil.log4Insert(dssUser);
            }
        }
    }

    /**
     * 查看数据资源审核详情
     *
     * @return 数据资源审核详情
     */
    public DataResourceDTO getSubscribeById(String id) {
        DssSubscribeDTO dssSubscribeDTO = this.selectByPrimaryKey(id);
        CheckParaUtils.checkDbObjectValidity(dssSubscribeDTO, logger, String.format("没有查到数据，请确保id:%s的订阅数据是否存在", id));

        DataResourceDTO dataResourceDTO = dataResourceService.getDataResourceById(dssSubscribeDTO.getDataResourceId());
        dataResourceDTO.setSubscribeDTO(dssSubscribeDTO);

        BdpLogUtil.log4Query(dataResourceDTO);
        return dataResourceDTO;
    }

    /**
     * 数据服务订阅
     *
     * @param dataResourceIds 数据服务ID列表，逗号分隔
     * @return 操作状态
     */
    public Boolean add(List<String> dataResourceIds) {
        CheckParaUtils.checkObjectValidity(dataResourceIds, logger, "订阅码必填");
        List<DssSubscribeDTO> list = new ArrayList<>();
        //用于记录日志
        List<String> nameList = Lists.newArrayList();

        for (String dataResourceId : dataResourceIds) {
            DataResourceDTO dataResourceDTO = dataResourceService.selectByPrimaryKey(dataResourceId);
            DssSubscribeDTO dto = new DssSubscribeDTO();
            dto.setId(ComUtil.getId());
            dto.setUserId(ThreadContextHelper.getUserId());
            dto.setDataResourceId(dataResourceId);
            dto.setAuditStatus(AuditStatus.APPLY.getCode());
            dto.setSecretLevel(dataResourceDTO.getSecretLevel());
            EntityUtils.setCreateAndUpdateInfo(dto);
            list.add(dto);

            //用于记录日志
            nameList.add(dataResourceDTO.getName());
        }

        //记录日志
        String logTitle = "服务订阅：资源【" + org.apache.commons.lang3.StringUtils.join(nameList,",") + "】";
        BdpLogUtil.log("服务订阅模块",logTitle, PlatformConstant.OpType.insert);

        return subscribeDao.insertListByBatch(list) >= 0;
    }

    /**
     * 取消订阅
     *
     * @param ids 数据服务订阅ID列表，逗号分隔
     * @return 操作状态
     */
    public Boolean delete(List<String> ids) {
        CheckParaUtils.checkObjectValidity(ids, logger, "订阅码必填");
        //用于记录日志
        List<String> nameList = Lists.newArrayList();
        for (String id : ids) {
            DssSubscribeDTO dssSubscribeDTO = subscribeDao.selectByPrimaryKey(id);
            //用于记录日志
            DataResourceDTO dataResourceDTO =
                    dataResourceService.selectByPrimaryKey(dssSubscribeDTO.getDataResourceId());
            nameList.add(dataResourceDTO.getName());

            if (dssSubscribeDTO == null) {
                throw new BusinessException("删除失败！对象不存在");
            }
            //删除业务数据
            deleteByPrimaryKey(id);
        }
        //记录日志
        String logTitle = "取消订阅：资源【" + org.apache.commons.lang3.StringUtils.join(nameList,",") + "】";
        BdpLogUtil.log("服务订阅模块",logTitle, PlatformConstant.OpType.delete);

        return true;
    }

    /**
     * 查询资源订阅人信息
     *
     * @param resourceId resourceId
     * @param pageNo     pageNo
     * @param pageSize   pageSize
     * @author felix
     */
    public QueryRespBean<DssSubscribeDTO> subscribeUsers(String resourceId,String keyWords, Integer pageNo,
                                                         Integer pageSize) {
        QueryRespBean<DssSubscribeDTO> queryRespBean = new QueryRespBean<>();
        try {
            if (StringUtils.isBlank(resourceId)) {
                throw new BusinessException("请检查参数！");
            }
            PageHelper.startPage(pageNo, pageSize);
            Page<DssSubscribeDTO> dataList = this.mapper.getSubscribeUsers(keyWords,resourceId);
            queryRespBean.setResult(dataList);
            BdpLogUtil.log4Query("服务监控模块", "用户列表", queryRespBean);
            return queryRespBean;
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }
    }

    /**
     * 查看审核意见
     *
     * @param id 订阅ID
     * @return 订阅DTO
     */
    public DssSubscribeDTO viewAudit(String id) {
        DssSubscribeDTO dssSubscribeDTO = this.selectByPrimaryKey(id);
        CheckParaUtils.checkDbObjectValidity(dssSubscribeDTO, logger, String.format("没有查到数据，请确保id:%s的订阅数据是否存在", id));

        String auditBy = dssSubscribeDTO.getAuditBy();
        if (StringUtils.isNotBlank(auditBy)) {
            dssSubscribeDTO.setAuditBy(sysUserClient.getSysUserById(auditBy).getName());
        }
        BdpLogUtil.log4Query(dssSubscribeDTO);
        return dssSubscribeDTO;
    }

    public List<DssSubscribeDTO> getSubscribeList(List<String> dataResourceIdList){
        return subscribeDao.getSubscribeList(dataResourceIdList);
    }

    /**
     * 添加订阅
     * @param subscribeDTO
     * @return
     */
    public void addSubscribe(DssSubscribeDTO subscribeDTO) {
        CheckParaUtils.checkObjectValidity(subscribeDTO.getDataResourceId(), logger, "数据资源ID必填");

        subscribeDTO.setId(ComUtil.getId());
        subscribeDTO.setUserId(ThreadContextHelper.getUserId());
        subscribeDTO.setAuditStatus(AuditStatus.APPLY.getCode());
        EntityUtils.setCreateAndUpdateInfo(subscribeDTO);
        this.insert(subscribeDTO);

        //用于记录日志
        DataResourceDTO dataResourceDTO = dataResourceService.selectByPrimaryKey(subscribeDTO.getDataResourceId());

        //记录日志
        String logTitle = "服务订阅：资源【" + dataResourceDTO.getName() + "】";
        BdpLogUtil.log("服务订阅模块", logTitle, PlatformConstant.OpType.insert);
    }

}
